package factory;


import enums.ExcelHeadBeanFlagEnum;
import headbean.*;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * TODO
 *
 * @author feng
 */
public class ExcelHeadMapFactory {
    /**
     * 全局表头名映射，ExcelHeadMapInterface实现类型为key，它内部变量的变量名和中文名映射为value
     */
    private static final Map<Class<? extends ExcelHeadMapInterface>, Map<String, String>> HEAD_NAME_MAP = new HashMap<>();

    /**
     * 转换器映射
     */
    public static final Map<Class<? extends ExcelHeadMapInterface>, Map<String,  Class<? extends Converter>>> COLUMN_CONVERTER_MAP = new HashMap<>();

    /**
     * 缓存converter 实例
     */
    public static final Map<Class<? extends Converter>, Converter<?>> CONVERTER_BEAN_MAP = new HashMap<>();

    public static void addHeadClass(Class<? extends ExcelHeadMapInterface> headClass) {
        HEAD_NAME_MAP.put(headClass, mapToPrepareHead(headClass));
    }

    public static Map<String, String> getHeadMap(Class<? extends ExcelHeadMapInterface> headClass) {
        return HEAD_NAME_MAP.get(headClass);
    }

    public static Map<String, String> getHeadMapByFlag(String flag) {
        return getHeadMap(ExcelHeadBeanFlagEnum.getHeadClass(flag));
    }

    private static Map<String, String> mapToPrepareHead(Class<? extends ExcelHeadMapInterface> excelHeadClass) {
        Map<String, String> namedMap = new HashMap<>();
        Map<String, Class<? extends Converter>> converterMap = new HashMap<>();
        Field[] declaredFields = excelHeadClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            boolean annotationPresent = declaredField.isAnnotationPresent(ExcelColumnTitle.class);
            if(annotationPresent) {
                ExcelColumnTitle excelProperty = declaredField.getAnnotation(ExcelColumnTitle.class);
                String chineseFieldName = excelProperty.value();
                // 保存字段名和中文变量名
                namedMap.put(declaredField.getName(), chineseFieldName);
                // 注册转换器
                Class<? extends Converter> converter = excelProperty.converter();
                if(converter != AutoConverter.class) {
                    converterMap.put(declaredField.getName(), converter);
                }
            }
        }

        COLUMN_CONVERTER_MAP.put(excelHeadClass, converterMap);

        // 生成converter实例
        converterMap.values().forEach(convertClass -> {
            try {
                Converter<?> converter = convertClass.newInstance();
                CONVERTER_BEAN_MAP.put(convertClass, converter);
            } catch (InstantiationException | IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        });
        return namedMap;
    }
}
